/*******************************************************************************
 * Copyright (c) 2008 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package fr.jade.fraclite.orb;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;

import org.objectweb.fractal.api.Interface;

import fr.jade.fraclite.orb.api.Marshaller;
import fr.jade.fraclite.orb.api.Name;
import fr.jade.fraclite.orb.api.RemoteReference;
import fr.jade.fraclite.orb.io.RmiMarshaller;
import fr.jade.fraclite.orb.names.JGroupsName;
import fr.jade.fraclite.orb.protocols.MulticastRpcClient;

/**
 * @author Sylvain Sicard
 * @author Florent Metral
 *
 */
public class MulticastStub implements InvocationHandler, RemoteReference {
  protected Logger log = Logger.getLogger(getClass().getName());
  protected MulticastRpcClient disp = null;
  protected JGroupsName id = null;
	protected Long stubId;
	protected Name name;

	public MulticastStub(Name name, Long stubId) {
	  //stubId = stubCounter++;
	  this.stubId = stubId;
	  this.name = name;
	  this.id = (JGroupsName)name;
		try {
			//channel = factoryStub.createMultiplexerChannel("udp", Long.toString(id.getItfId()));
			//disp=new HARpcDispatcher(channel, null, null, null);
			Marshaller m = new RmiMarshaller(name.getNaming());
			disp=new MulticastRpcClient(stubId, id.getGroupId(), m);
			//log.fine("[stub] connect "+id.getGroupId());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
		//System.out.println("Call " + m.getName() + " group:" + id.getGroupId()+" callId: "+callId);
		try{
			MulticastStub.class.getMethod(m.getName(), m.getParameterTypes());
			Object res =  m.invoke(this, args);
			return res;
		}catch(NoSuchMethodException e){
			Object res=disp.callRemoteMethods(m, args);
			if(res!=null && res instanceof Exception){
				throw (Exception)res;
			}else{
				//System.out.println("result: " + res);
				return res;
			}
		}
	}

	@Override
	public boolean equals(Object o){
	  if (o instanceof Interface) {
      return id.getItfId()==((Interface)o).getFcItfGUId();
    }else{
      return false;
    }
	}

  @Override
  public Name getName() {
    return name;
  }

}
